﻿//----------------------------------------------------------------------------------------------------
// A NodeInstance is the representation of a node in a level
//----------------------------------------------------------------------------------------------------

package HG.Visual
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.Point;
	
	import fl.transitions.Tween;
	import fl.transitions.easing.*;
	import fl.transitions.TweenEvent;
	
	import HG.Visual.VisualAttachPoint;
	
	import HG.GameService;
	import HG.Managers.PlayerManager;
	import HG.Managers.VisibilityManager;
	import HG.Actions.IAction;
	import HG.Managers.LevelManager;
	
	public class VisualNode extends VisualObject
	{
		var m_type:String;
		var m_ID:Number;
		var m_source:VisualAttachPoint;
		var m_connections:Array;
		var m_pendingAction:IAction;
		
		var m_sentryTripChance:Array;
		
		var m_playerManager:PlayerManager;
		var m_levelManager:LevelManager;
		
		var m_hasEnemy:Boolean;
		var m_hasFriend:Boolean;
		
		// Actions
		var m_ocupants:Array;
		
		var m_encryption:Number;
		
		//visibility
		var m_encryptionOverlayOpen:Boolean;
		
		//----------------------------------------------------------------------------------------------------
		public function VisualNode(typeString:String, ID:Number)
		{
			super();
			
			SetType(typeString);
			m_ID = ID;
			
			m_connections = new Array();
			m_ocupants = new Array();
			
			m_playerManager = GameService.GetInstance().GetPlayerManager();
			m_levelManager = GameService.GetInstance().GetLevelManager();
			
			m_open = false;
			
			m_encryption = 0;
			m_pendingAction = null;
			
			m_sentryTripChance = new Array();
			
			m_hasEnemy = false;
			m_hasFriend = false;
			
			Content.State.Enemy.visible = false;
			Content.State.Enemy.alpha = 0;
			Content.State.Friend.visible = false;
			Content.State.Friend.alpha = 0;
			
			m_encryptionOverlayOpen = false;
			
			UpdateEncryption();
			UpdateOwnership();
			
			ClearPendingAction();
			Content.Pending.alpha = 0;
		}

		//----------------------------------------------------------------------------------------------------
		public function SetType(type:String)
		{
			m_type = type;
			
			Content.Icon.gotoAndStop(m_type);
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetType():String
		{
			return m_type;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetID():Number
		{
			return m_ID;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function ClearSource()
		{
			if (m_source)
					m_source.SetAvailable(true);
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetSource():VisualAttachPoint
		{
			return m_source;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function SetSource(attach:VisualAttachPoint, temporary:Boolean)
		{
			if (!temporary)
			{
				if (m_source)
					m_source.SetAvailable(true);
					
				m_source = attach;
				m_source.SetAvailable(false);
				
				m_source.SetVisualNodeID(m_ID);
				
				trace("SET SOURCE " + m_source.GetID());
			}
				
			this.x = attach.x;
			this.y = attach.y;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function AddConnection(toID:Number)
		{
			m_connections.push(toID);
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetConnections():Array
		{
			return m_connections;
		}
		//----------------------------------------------------------------------------------------------------
		public function RemoveConnection(toID:Number)
		{
			var index:Number = 0;
			var listLength:Number = m_connections.length;
			for (index = 0; index < listLength; ++index)
			{
				if (m_connections[index] == toID)
				{
					m_connections.splice(index, 1);
					return;
				}
			}
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetIsConnectedTo(toID:Number):Boolean
		{
			var index:Number = 0;
			var listLength:Number = m_connections.length;
			for (index = 0; index < listLength; ++index)
			{
				if (m_connections[index] == toID)
					return true;
			}
			
			return false;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function UpdateOwnership()
		{
			var isPlayerOcupied = GetIsOcupiedBy(m_playerManager.GetCurrentPlayerID());
			
			var hasFriend:Boolean = isPlayerOcupied;
			
			var numOcupants = m_ocupants.length;
			if (isPlayerOcupied)
				numOcupants--;
			
			
			var hasEnemy:Boolean = (numOcupants != 0);
			
			
			if (hasEnemy && !m_hasEnemy)
			{
				// Just got enemy
				Content.State.Enemy.visible = true
				new Tween(Content.State.Enemy, "alpha", Strong.easeInOut, Content.State.Enemy.alpha, 1, 2, true);
			}
			else if (m_hasEnemy && !hasEnemy)
			{
				// Just lost enemy
				new Tween(Content.State.Enemy, "alpha", Strong.easeInOut, Content.State.Enemy.alpha, 0, 2, true);
			}
			m_hasEnemy = hasEnemy
			
		
			if (hasFriend && !m_hasFriend)
			{
				// Just got friend
				Content.State.Friend.visible = true;
				new Tween(Content.State.Friend, "alpha", Strong.easeInOut, Content.State.Enemy.alpha, 1, 2, true);
			}
			else if (m_hasFriend && !hasFriend)
			{
				// Just lost friend
				new Tween(Content.State.Friend, "alpha", Strong.easeInOut, Content.State.Enemy.alpha, 0, 2, true);
			}
			m_hasFriend = hasFriend
			
			UpdateConnections();
		}
		
		//----------------------------------------------------------------------------------------------------
		public function UpdateConnections()
		{
			var index:Number = 0;
			var listLength:Number = m_connections.length;
			
			for (index = 0; index < listLength; ++index)
			{
				var conTo:Number = m_connections[index];
				
				var visCon:VisualConnection = m_levelManager.GetVisualConnection(GetID(), conTo);
				
				visCon.Update();
			}
		}
		
		//----------------------------------------------------------------------------------------------------
		public function UpdateEncryption()
		{
			if (m_type == "Document")
			{
				Content.EncryptionIcon.visible = false;
				Content.EncryptionOverlay.visible = false;
				return;
			}
			
			Content.EncryptionOverlay.visible = true;
			if (m_encryption != 0)
			{
				if (!m_encryptionOverlayOpen)
				{
					Content.EncryptionOverlay.gotoAndPlay('in');
					m_encryptionOverlayOpen = true;
				}
			}
			else
			{
				if (m_encryptionOverlayOpen)
				{
					Content.EncryptionOverlay.gotoAndPlay('out');
					m_encryptionOverlayOpen = false;
				}
			}
			
			
			Content.EncryptionIcon.visible = (m_encryption != 0);
			Content.EncryptionIcon.Icon.SetValue(m_encryption);
		}
		
		//----------------------------------------------------------------------------------------------------
		public function SetPendingAction(action:IAction)
		{
			// we dont want to see AI pending actions, do we?
			if (action.GetOwner() != m_playerManager.GetCurrentPlayerID())
				return;
			
			Content.Pending.Icon.gotoAndStop(action.GetType());
			
			m_pendingAction = action;
			
			new Tween(Content.Pending, "alpha", Strong.easeInOut, Content.Pending.alpha, 1, 1, true);
			new Tween(Content.Icon, "alpha", Strong.easeInOut, Content.Icon.alpha, 0.5, 1, true);
			
			UpdateConnections();
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetPendingAction():IAction
		{
			return m_pendingAction;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function ClearPendingAction()
		{
			new Tween(Content.Pending, "alpha", Strong.easeInOut, Content.Pending.alpha, 0, 1, true);
			new Tween(Content.Icon, "alpha", Strong.easeInOut, Content.Icon.alpha, 1, 1, true);
			
			m_pendingAction = null;
			
			Content.Progress.Reset();
		}
		
		//----------------------------------------------------------------------------------------------------
		public function ClearPendingActionForPlayer(playerID:Number)
		{
			if (!m_pendingAction)
				return;
				
			if (m_pendingAction.GetOwner() == playerID)
				ClearPendingAction();
		}
		
		//----------------------------------------------------------------------------------------------------
		public function SetProgressDisplay(val:Number, friendly:Boolean)
		{
			if (friendly)
			{
				Content.Progress.Content.Color.gotoAndStop("green");
			}
			else
			{
				Content.Progress.Content.Color.gotoAndStop("red");
			}
			
			Content.Progress.SetValue(val);
		}
		
		//----------------------------------------------------------------------------------------------------
		// Action hooks
		//----------------------------------------------------------------------------------------------------
		public function AddOcupant(playerID:Number)
		{
			if (!GetIsOcupiedBy(playerID))
			{
				m_ocupants.push(playerID);
				UpdateOwnership();
			}
		}
		
		//----------------------------------------------------------------------------------------------------
		public function RemoveOcupant(playerID:Number)
		{
			var index:Number = 0;
			var listLength:Number = m_ocupants.length;
			
			for (index = 0; index < listLength; ++index)
			{
				if (m_ocupants[index] == playerID)
				{
					m_ocupants.splice(index, 1);
				}
			}	
				
			UpdateOwnership();
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetOcupants():Array
		{
			return m_ocupants;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetIsOcupiedBy(playerID:Number):Boolean
		{
			var index:Number = 0;
			var listLength:Number = m_ocupants.length;
			
			for (index = 0; index < listLength; ++index)
			{
				if (m_ocupants[index] == playerID)
					return true;
			}	
			
			return false;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetIsOcupiedByAnyoneBut(playerID:Number):Boolean
		{
			var index:Number = 0;
			var listLength:Number = m_ocupants.length;
			
			for (index = 0; index < listLength; ++index)
			{
				if (m_ocupants[index] != playerID)
					return true;
			}	
			
			return false;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function SetEncryptionKey(key:Number)
		{
			m_encryption = key;
			UpdateEncryption();
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetEncryptionKey():Number
		{
			return m_encryption;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function SetTripChances(chances:Array)
		{
			m_sentryTripChance = chances;
		}
		
		//----------------------------------------------------------------------------------------------------
		public function GetTripChances():Array
		{
			return m_sentryTripChance;
		}
		
		//----------------------------------------------------------------------------------------------------
	}
}







